package com.example.networklab.service.impl;

import com.example.networklab.common.BizException;
import com.example.networklab.common.ExceptionEnum;
import com.example.networklab.domain.po.StudentGrade;
import com.example.networklab.domain.po.Task;
import com.example.networklab.domain.po.User;
import com.example.networklab.domain.vo.FinalScoreVO;
import com.example.networklab.domain.vo.ListVO;
import com.example.networklab.enums.TaskStatus;
import com.example.networklab.mapper.StudentGradeMapper;
import com.example.networklab.mapper.TaskMapper;
import com.example.networklab.service.IStudentGradeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.networklab.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生成绩表 服务实现类
 * </p>
 *
 * @author dzw
 * @since 2025-02-27
 */
@Service
@RequiredArgsConstructor
public class StudentGradeServiceImpl extends ServiceImpl<StudentGradeMapper, StudentGrade> implements IStudentGradeService {
    private final TaskMapper taskMapper;
    private final IUserService userService;

    @Override
    public ListVO<FinalScoreVO> teaGetTaskGrade(Long taskId) {
        Task task = taskMapper.selectById(taskId);
        if (task.getStatus() != TaskStatus.END || task.getEndTime().isAfter(LocalDateTime.now())) {
            throw new BizException(ExceptionEnum.TASK_NOT_END);
        }
        List<StudentGrade> studentGrades = this.lambdaQuery()
                .eq(StudentGrade::getTaskId, taskId)
                .list();
        List<User> userList = getUserList(task);
        ArrayList<FinalScoreVO> res = new ArrayList<>(userList.size());
        Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, user -> user));
        for (StudentGrade studentGrade : studentGrades) {
            FinalScoreVO finalScoreVO = new FinalScoreVO();
            finalScoreVO.setUserId(studentGrade.getUserId());
            finalScoreVO.setScore(studentGrade.getScore());
            User user = userMap.get(studentGrade.getUserId());
            if (user != null) {
                finalScoreVO.setUsername(user.getUsername());
                finalScoreVO.setName(user.getName());
                userMap.remove(studentGrade.getUserId());
            }
            res.add(finalScoreVO);
        }
        if (!userMap.isEmpty()) {
            List<StudentGrade> notSubmit = new ArrayList<>(userMap.size());
            for (User user : userMap.values()) {
                FinalScoreVO finalScoreVO = new FinalScoreVO();
                finalScoreVO.setUserId(user.getUserId());
                finalScoreVO.setUsername(user.getUsername());
                finalScoreVO.setName(user.getName());
                finalScoreVO.setScore(0);
                StudentGrade studentGrade = new StudentGrade();
                studentGrade.setTaskId(taskId);
                studentGrade.setUserId(user.getUserId());
                studentGrade.setScore(0);
                notSubmit.add(studentGrade);
                res.add(finalScoreVO);
            }
            this.saveBatch(notSubmit);
        }
        return new ListVO<>(res);
    }

    private List<User> getUserList(Task task) {
        return userService.lambdaQuery()
                .eq(User::getGrade, task.getGrade())
                .eq(User::getClassNum, task.getClassNum())
                .list();
    }
}
